﻿<?xml version="1.0" encoding="utf-8" ?>

<scope
	xmlns="http://metalx.org/Program"
	xmlns:cpu16="http://metalx.org/Intel/80286/Operators"
	xmlns:cpu32="http://metalx.org/Intel/80386/Operators"
	xmlns:op16="http://metalx.org/Intel/80286/Operands"
	xmlns:op32="http://metalx.org/Intel/80386/Operands"
	xmlns:ex16="http://metalx.org/Intel/80286/ExtendedOperators"
	xmlns:math16="http://metalx.org/Intel/80286/Math"
	xmlns:seg16="http://metalx.org/Intel/80286/Segments"
	xmlns:seg32="http://metalx.org/Intel/80386/Segments"
	xmlns:imm32="http://metalx.org/Intel/80386/Immediate"
	xmlns:ctrl16="http://metalx.org/Intel/80286/Control"
	xmlns:gdt16="http://metalx.org/Intel/80286/DescriptorTable"
	xmlns:gdt32="http://metalx.org/Intel/80386/DescriptorTable"
	xmlns:sys="http://metalx.org/Pc/Bios/System"
	xmlns:bios="http://metalx.org/Pc/Bios/Functions"
	xmlns:logic32="http://metalx.org/Intel/80386/Logic"
	xmlns:pic="http://metalx.org/Pc/Pic/Ports"
	xmlns:cmd="http://metalx.org/Pc/Pic/Commands"
	xmlns:dsk="http://metalx.org/i286/Functions/Disk"
	xmlns:hd="http://metalx.org/i386/Functions/HardDrive"
	xmlns:imm16="http://metalx.org/Intel/80286/Immediate"
	xmlns:inc16="http://metalx.org/Intel/80286/Increment"
	xmlns:inc32="http://metalx.org/Intel/80386/Increment"
	xmlns:hex32="http://metalx.org/i386/Functions/Hexadecimal"
	xmlns:con="http://metalx.org/i286/Functions/Console">

	<!--Set CPU To Known State-->
	<cpu16:ClearDirectionFlag/>

	<cpu16:CopyImmediateToAX/>
	<hex>0000</hex>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:SS-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:DS-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:ES-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:FS-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:GS-AXRegister/>

	<cpu16:CopyRegisterToOperand16/>
	<op16:AX-SPRegister/>

	<cpu16:JumpToImmediatePointer16/>
	<addressOf ref="start" type="Pointer16"/>

	<label id="start"/>

	<!--Enable A20 Gate-->
	<cpu16:CopyImmediateToAX/>
	<sys:EnableA20Gate/>

	<cpu16:CallImmediate8Interrupt/>
	<bios:SystemFunctions/>

	<!--Get Memory Map-->
	<cpu16:Operand32/>
	<cpu16:CopyImmediateToDI/>
	<hex>00003000</hex>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToBX/>
	<int>0</int>

	<label id="nextEntry"/>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToAX/>
	<hex>0000e820</hex>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToDX/>
	<string>PAMS</string>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToCX/>
	<int>24</int>

	<cpu16:CallImmediate8Interrupt/>
	<bios:SystemFunctions/>

	<cpu16:MathImmediate8ToOperand16Function/>
	<math16:AddToDIRegister/>
	<byte>24</byte>

	<cpu16:BranchToRelativeIfCarry8/>
	<addressOf ref="done" type="Relative8"/>

	<cpu16:MathImmediateToOperandFunction16/>
	<math16:CompareWithBXRegister/>
	<hex>0000</hex>

	<cpu16:BranchToRelativeIfEqual8/>
	<addressOf ref="done" type="Relative8"/>

	<cpu16:JumpToRelative8/>
	<addressOf ref="nextEntry" type="Relative8"/>

	<label id="done"/>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToOperandFunction16/>
	<imm16:CopyImmediateToDIAddress/>
	<hex>ffffffff</hex>

	<!--Get Extended Display Information Data (EDID)-->
	<cpu16:Operand32/>
	<cpu16:CopyImmediateToDI/>
	<hex>00003200</hex>

	<cpu16:CopyImmediateToAX/>
	<hex>4f15</hex>

	<cpu16:CopyImmediateToBX/>
	<short>1</short>

	<cpu16:CallImmediate8Interrupt/>
	<hex>10</hex>

	<!--Disable NMI-->
	<cpu16:ReadFromImmediate8PortToAL/>
	<hex>70</hex>

	<cpu16:OrALWithImmediate/>
	<binary>10000000</binary>

	<cpu16:WriteALToImmediate8Port/>
	<hex>70</hex>

	<!--Load Global Descriptor Table-->
	<cpu16:ClearInterruptFlag/>

	<cpu16:ExtendedOperator/>
	<ex16:DescriptorTableFunction/>
	<gdt16:CopyImmediate16AddressToGlobalDescriptorTableRegister/>
	<addressOf ref="globalDescriptorTablePointer" type="Absolute16"/>

	<!--Switch To 32-Bit Protected Mode-->
	<cpu16:ExtendedOperator/>
	<ex16:CopyControlRegisterToRegister/>
	<ctrl16:AX-ControlRegister0/>

	<cpu16:OrALWithImmediate/>
	<binary>00000001</binary>

	<cpu16:ExtendedOperator/>
	<ex16:CopyRegisterToControlRegister/>
	<ctrl16:AX-ControlRegister0/>

	<!--Jump to segment-->
	<cpu16:JumpToImmediatePointer16/>
	<addressOf ref="enterProtectedMode" type="Absolute16"/>
	<hex>0008</hex>

	<!--32-bit Protected Mode-->
	<label id="enterProtectedMode"/>

	<!--Enable NMI-->
	<cpu32:ReadFromImmediate8PortToAL/>
	<hex>70</hex>

	<cpu32:AndALWithImmediate/>
	<binary>01111111</binary>

	<cpu32:WriteALToImmediate8Port/>
	<hex>70</hex>

	<!--Setup Segment Registers-->
	<cpu32:CopyImmediateToAX/>
	<hex>00000010</hex>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:SS-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:DS-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:ES-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:FS-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:GS-AXRegister/>

	<cpu32:CopyImmediateToSP/>
	<hex>00010000</hex>

	<!--Reprogram Master Interrupt Controller-->
	<cpu32:CopyImmediateToAL/>
	<cmd:InitializeForEnvironment/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterCommand/>

	<cpu32:CopyImmediateToAL/>
	<byte>32</byte>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<cpu32:CopyImmediateToAL/>
	<binary>00000100</binary>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<cpu32:CopyImmediateToAL/>
	<cmd:Environment8086Mode/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<cpu32:CopyImmediateToAL/>
	<hex>00</hex>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<!--Reprogram Slave Interrupt Controller-->
	<cpu32:CopyImmediateToAL/>
	<cmd:InitializeForEnvironment/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveCommand/>

	<cpu32:CopyImmediateToAL/>
	<byte>40</byte>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToAL/>
	<binary>00000010</binary>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToAL/>
	<cmd:Environment8086Mode/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToAL/>
	<hex>00</hex>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToDX/>
	<hex>000003f6</hex>

	<hd:ResetController/>

	<!--Read Disk Information From Hard Drive-->
	<cpu32:CopyImmediateToDI/>
	<hex>00010000</hex>

	<cpu32:CopyImmediateToAX/>
	<int>1</int>

	<cpu32:CopyImmediateToBX/>
	<int>0</int>

	<cpu32:CopyImmediateToCX/>
	<int>1</int>

	<cpu32:CopyImmediateToDX/>
	<hex>000001f0</hex>
	
	<cpu32:CallRelative/>
	<addressOf ref="readBlocks" type="Relative32"/>
	
	<cpu32:CopyOperandToRegister/>
	<op32:AX-DIAddressPlusImmediate8/>
	<byte>16</byte>

	<cpu32:CopyOperandToRegister/>
	<op32:CX-DIAddressPlusImmediate8/>
	<byte>20</byte>

	<cpu32:LogicFunction/>
	<logic32:PushDIAddressPlusImmediate8/>
	<byte>52</byte>

	<cpu32:CallRelative/>
	<addressOf ref="readBlocks" type="Relative32"/>

	<!--Read Programs From Hard Drive-->
	<cpu32:CopyRegisterToOperand/>
	<op32:DI-SIRegister/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:CopyRegisterToOperand/>
	<op32:AX-CXRegister/>

	<label id="forEachProgram"/>

	<cpu32:PushCXToStack/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:PushAXToStack/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:CopyRegisterToOperand/>
	<op32:AX-CXRegister/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:CopyRegisterToOperand/>
	<op32:AX-DIRegister/>

	<cpu32:PullAXFromStack/>

	<cpu32:CallRelative/>
	<addressOf ref="readBlocks" type="Relative32"/>

	<cpu32:PullCXFromStack/>

	<cpu32:LoopToRelative8/>
	<addressOf ref="forEachProgram" type="Relative8"/>

	<!--Restore Start Address-->
	<cpu16:PullSIFromStack/>

	<!--Jump To Second Boot Loader-->
	<cpu32:JumpToImmediatePointer/>
	<hex>00008000</hex>
	<hex>00000008</hex>

	<!--Global Descriptor Table Pointer-->
	<label id="globalDescriptorTablePointer"/>
	<hex>0017</hex>
	<addressOf ref="globalDescriptorTable" type="Absolute16"/>

	<!--Global Descriptor Table-->
	<label id="globalDescriptorTable"/>
	<!--Null Descriptor (0000)-->

	<!--Size-->
	<hex>0000</hex>
	<!--Base (Low)-->
	<hex>0000</hex>
	<!--Base (Mid)-->
	<hex>00</hex>
	<!--Access-->
	<binary>00000000</binary>
	<!--Flags / Size (High)-->
	<binary>00000000</binary>
	<!--Base (High)-->
	<hex>00</hex>

	<!--Code Descriptor (0008)-->

	<!--Size-->
	<hex>ffff</hex>
	<!--Base (Low)-->
	<hex>0000</hex>
	<!--Base (Mid)-->
	<hex>00</hex>
	<!--Access-->
	<binary>10011010</binary>
	<!--Flags / Size (High)-->
	<binary>11001111</binary>
	<!--Base (High)-->
	<hex>00</hex>

	<!--Data Descriptor (0010)-->

	<!--Size-->
	<hex>ffff</hex>
	<!--Base (Low)-->
	<hex>0000</hex>
	<!--Base (Mid)-->
	<hex>00</hex>
	<!--Access-->
	<binary>10010010</binary>
	<!--Flags / Size (High)-->
	<binary>11001111</binary>
	<!--Base (High)-->
	<hex>00</hex>

	<!--Functions-->
	<label id="readBlocks"/>

	<cpu32:PushSIToStack/>
	<cpu32:PushDIToStack/>
	<cpu32:PushBXToStack/>

	<hd:ReadBlocks/>

	<cpu32:PullBXFromStack/>
	<cpu32:PullDIFromStack/>
	<cpu32:PullSIFromStack/>

	<cpu32:ReturnToNearCaller/>
</scope>